from typing import Dict, List, Tuple
from Course_Management_and_Enrollment.course_task_classes import Course
from User_Management.user_classes import Student


class EnrollmentSystem:
    #选课系统,处理学生选课、退课及规则验证
    
    def __init__(self):
        self._enrollment_records: Dict[str, List[str]] = {}  # 选课记录:{course_id: [student_id列表]}
        self.student_enrollments: Dict[str, List[str]] = {}  # 学生选课记录:{student_id: [course_id列表]}

    def validate_enrollment(self, student: Student, course: Course) -> Tuple[bool, str]:
        #验证选课合法性,返回(是否通过, 提示信息)
        # 检查学生是否已选课
        if course.check_enrollment_status(student):
            return False, f"Student {student.name} has enrolled Course {course.course_name}"
        # 检查课程是否满员
        if course.current_enrollment >= course.max_students:
            return False, f"Course {course.course_name} has reached its maximum capacity({course.max_students})"
        # 其他验证(如学生是否被禁用、课程是否开放选课等)
        if not student.is_active:  # 假设Student类有is_active属性
            return False, f"Student {student.name} enrollment blocked due to status"
        return True, "Enrollment verfication successful"

    def process_enrollment(self, student: Student, course: Course) -> bool:
        #执行选课操作(需先通过验证)
        valid, msg = self.validate_enrollment(student, course)
        if not valid:
            print(f"Enrollment failed:{msg}")
            return False
        
        # 调用Course的私有方法添加学生(封装保护)
        if course._add_student(student):
            # 更新选课记录
            if course.course_id not in self._enrollment_records:
                self._enrollment_records[course.course_id] = []
            self._enrollment_records[course.course_id].append(student.student_id)
            
            # 更新学生选课记录
            if student.student_id not in self.student_enrollments:
                self.student_enrollments[student.student_id] = []
            self.student_enrollments[student.student_id].append(course.course_id)
            
            print(f"Student {student.name} enrollment Course {course.course_name} successful")
            return True
        return False

    def process_drop(self, student: Student, course: Course) -> bool:
        #执行退课操作
        if not course.check_enrollment_status(student):
            print(f"Drop course fail:Student {student.name} didn't enroll Course {course.course_name}")
            return False
        
        # 调用Course的私有方法移除学生
        if course._remove_student(student):
            # 更新选课记录
            if course.course_id in self._enrollment_records:
                self._enrollment_records[course.course_id].remove(student.student_id)
                # 若课程无学生,删除记录键
                if not self._enrollment_records[course.course_id]:
                    del self._enrollment_records[course.course_id]
            
            # 更新学生选课记录
            if student.student_id in self.student_enrollments:
                self.student_enrollments[student.student_id].remove(course.course_id)
                if not self.student_enrollments[student.student_id]:
                    del self.student_enrollments[student.student_id]
            
            print(f"Student {student.name} drop Course {course.course_name} successful")
            return True
        return False

    def get_enrollment_records(self) -> Dict[str, List[str]]:
        #返回选课记录副本(避免外部修改)
        return {k: v.copy() for k, v in self._enrollment_records.items()}
    
    def enroll_student(self, student, course):
        """学生选课"""
        # 检查学生是否已选该课程
        if course in student.enrolled_courses:
            return False, f"Student {student.username} has enrolled Course {course.course_name}"
        
        # 检查课程是否已满
        if len(course.enrolled_students) >= course.max_students:
            return False, f"Student {student.username} enrollment blocked due to status"
        
        # 选课成功
        student.enrolled_courses.append(course)
        course.enrolled_students.append(student)
        
        # 更新选课记录
        if course.course_id not in self._enrollment_records:
            self._enrollment_records[course.course_id] = []
        self._enrollment_records[course.course_id].append(student.student_id)
        
        # 更新学生选课记录
        if student.student_id not in self.student_enrollments:
            self.student_enrollments[student.student_id] = []
        self.student_enrollments[student.student_id].append(course.course_id)
        
        print(f"Student {student.username} enrollment Course {course.course_name} successful")
        return True, "Enrollment successful"

    def drop_student(self, student, course=None, student_id=None, course_id=None):
        """学生退课 - 支持对象或ID参数"""
        # 处理对象参数
        if student and course:
            if course not in student.enrolled_courses:
                print(f"Drop course fail:Student {student.username} didn't enroll Course {course.course_name}")
                return False
            
            student.enrolled_courses.remove(course)
            course.enrolled_students.remove(student)
            
            # 更新记录
            if course.course_id in self._enrollment_records:
                if student.student_id in self._enrollment_records[course.course_id]:
                    self._enrollment_records[course.course_id].remove(student.student_id)
                    if not self._enrollment_records[course.course_id]:
                        del self._enrollment_records[course.course_id]
            
            if student.student_id in self.student_enrollments:
                if course.course_id in self.student_enrollments[student.student_id]:
                    self.student_enrollments[student.student_id].remove(course.course_id)
                    if not self.student_enrollments[student.student_id]:
                        del self.student_enrollments[student.student_id]
            
            print(f"Student {student.username} drop Course {course.course_name} successful")
            return True
        
        # 处理ID参数
        elif student_id and course_id:
            if course_id in self.student_enrollments.get(student_id, []):
                self.student_enrollments[student_id].remove(course_id)
                if not self.student_enrollments[student_id]:
                    del self.student_enrollments[student_id]
                
                # 更新课程记录
                for c_id, students in self._enrollment_records.items():
                    if c_id == course_id and student_id in students:
                        students.remove(student_id)
                        if not students:
                            del self._enrollment_records[c_id]
                        break
                
                print(f"学生 {student_id} 已退选课程 {course_id}")
                return True
            print("未选该课程,退课失败")
            return False
        
        print("退课参数不完整")
        return False
        
    def add_course(self, course):
        """添加课程到选课系统(仅用于初始化)"""
        # 这个方法主要是为了兼容load_courses_and_enrollment函数
        # 实际的选课系统不需要存储课程对象,只需要记录选课关系
        pass
